REM Initialise Director's Bin
REM Title:      Director:Menus.BinPL.BinInit
REM Author:     Philip Ludlam
REM Version:    0.16 Beta, 14 September 2002
REM Copyright:  (C) Philip Ludlam 2002

REM This program is free software; you can redistribute it and/or modify it
REM under the terms of the GNU General Public License as published by the Free
REM Software Foundation; either version 2 of the License, or (at your option)
REM any later version.
REM
REM This program is distributed in the hope that it will be useful, but WITHOUT
REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
REM FITNESS FOR APARTICULAR PURPOSE. See the GNU General Public License for more
REM details.
REM
REM You should have received a copy of the GNU General Public License along with
REM this program; if not, write to the Free Software Foundation, Inc., 59 Temple
REM Place - Suite 330, Boston, MA 02111-1307, USA

REM VDU4:*SPOOL SCSI::4.$.Data
REM TRACE ON

ON ERROR PROCerror

DIM now% 5, block% 1023, wblock% 255

REM Get command line. Decode command line

SYS "OS_GetEnv" TO comm%
SYS "OS_ReadArgs","name,quit,delete/s",comm%,block%,1023
IF block%!8<>0 THEN args_delete%=TRUE ELSE args_delete%=FALSE

REM Initialise variables, and set them to default values
log_binned%=FALSE:log_create%=2:log_show%=2:log_created%=FALSE
bin_file%=0:file%=0
REM bin_dir$=FNreadvarval("Bin$Dir")
bin_day$=""
REM bin_path$=bin_dir$+bin_day$
bin_all%=FALSE
REM scrap_dir$=FNreadvarval("Wimp$ScrapDir")
SYS "OS_FSControl",37,"<Wimp$ScrapDir>",block%,,,1023 TO ,,,,,t%
scrap_dir$=FNstring(block%)
scrap_len%=LEN(scrap_dir$)

REM Default settings
bin_dir$="<Wimp$ScrapDir>.Bin"
remove_days%=7
remove_style%=1

REM Load BinConfig file and read log/directory settings
file%=OPENIN("Director:Menus.BinPL.BinConfig")
line$=""
WHILE NOT EOF#file% AND LEFT$(line$,5)<>"allow"
  line$=FNfile_line_process

  IF LEFT$(line$,9)="directory" bin_dir$=MID$(line$,11)

  IF LEFT$(line$,10)="removedays" remove_days%=FNeval(MID$(line$,12))


  IF LEFT$(line$,11)="removestyle" THEN
    CASE MID$(line$,13) OF
      WHEN "multi"  : remove_style%=1
      WHEN "single" : remove_style%=2
    ENDCASE
  ENDIF

  IF LEFT$(line$,3)="log" THEN
    CASE MID$(line$,5) OF
      WHEN "always" : log_create%=1
      WHEN "binned" : log_create%=2
      WHEN "never"  : log_create%=3
    ENDCASE
  ENDIF

  IF LEFT$(line$,4)="show" THEN
    CASE MID$(line$,6) OF
      WHEN "all"    : log_show%=1
      WHEN "binned" : log_show%=2
    ENDCASE
  ENDIF

  IF LEFT$(line$,4)="changeicon" THEN
    CASE MID$(line$,6) OF
      WHEN "yes" : change_icon%=TRUE
      WHEN "no"  : change_icon%%=FALSE
    ENDCASE
  ENDIF

ENDWHILE
CLOSE#file%:file%=0

IF FNlcase(LEFT$(bin_dir$,9))="director:" bin_dir$="<Director$Write>."+MID$(bin_dir$,10)
IF FNlcase(LEFT$(bin_dir$,15))="<director$path>" bin_dir$="<Director$Write>"+MID$(bin_dir$,15)
SYS "OS_FSControl",37,bin_dir$+".^",block%,,,1023:bin_parent$=FNstring(block%)

REM Get current date.

?now%=3
SYS "OS_Word",14,now%
SYS "OS_ConvertDateAndTime",now%,block%,11,"%ce%yr-%mn-%dy" TO ,zero%
?zero%=13

bin_day$=FNstring(block%)
bin_path$=bin_dir$+"."+bin_day$+"."


REM Create directories

OSCLI("Set Bin$Day  "+bin_day$)
OSCLI("Set Bin$Dir  "+bin_dir$)
OSCLI("Set Bin$Path <Bin$Dir>.")
OSCLI("Set BinDay$Path "+bin_path$)
OSCLI("Set BinParent$Dir "+bin_parent$)
OSCLI("Set BinLeaf$Dir  "+FNfile_leaf(bin_dir$))

PROCfile_createdir(bin_dir$+"."+bin_day$)


REM Create Bin Icon
bin_$="Bin"
IF NOT FNfile_valid("BinDay:*",0) bin_$="Bin_Full"
IF args_delete%=TRUE THEN bin_$="Bin_Full"
?now%=3
SYS "OS_Word",14,now%
SYS "OS_ConvertDateAndTime",now%,block%,11,"%dy/%mn/%ce%yr" TO ,zero%
?zero%=13

_part$="-select ""Command:Filer_OpenDir |<Bin$Dir>"" -adjust ""Command:Filer_OpenDir |<Bin$Dir>"" -menu Bin -dragto ""Command:/Director:Menus.BinPL.DelFiles"""
OSCLI("DirectorIcon "+bin_$+" -alias bin """+FNstring(block%)+""" -left -priority &0E000001 -time %dy/%mn/%ce%yr "+_part$)


REM Delete expired bin directories
IF NOT args_delete% THEN
  app$="Director:Bin"
  SYS "Wimp_Initialise",200,&4B534154,app$ TO taskid%
  ON ERROR PROCwimp_error(REPORT$+" at line "+STR$ ERL)

  PROCdelete_bin

  SYS "Wimp_CloseDown",taskid%,&4B534154
ENDIF

END

:

DEF PROCdelete_bin
LOCAL del%:deleted%=TRUE
delete$=FNsubtract_day
WHILE deleted%
  deleted%=FALSE
  SYS "OS_GBPB",10,bin_dir$,block%,1,0,1023 TO ,,,r3%,r4%
  WHILE r4%<>-1
    IF r3%<>0 THEN
      dir$=FNstring(block%+20)
REM      PRINT dir$,r3%,r4%,deleted%
      IF dir$<delete$ THEN
        CASE remove_style% OF
          WHEN 1 : REM Multi
          SYS "Wimp_StartTask","/Director:Menus.BinPL.DelBin "+dir$
            PROCwimp_poll(0)
          WHEN 2 : REM Single
            SYS "Wimp_StartTask","%Wipe "+bin_dir$+"."+dir$+" ~CFR~V"
            REM PROCwimp_poll(0)
            deleted%=TRUE
        ENDCASE
REM        PRINT '"Deleted: "+dir$''
      ENDIF
    ENDIF
    SYS "OS_GBPB",10,bin_dir$,block%,r3%,r4%,1023 TO ,,,r3%,r4%
  ENDWHILE
ENDWHILE
ENDPROC

:

DEF PROCwimp_poll(flags%)
SYS "Wimp_Poll",flags%,wblock% TO reason%
CASE reason% OF
  WHEN 2: SYS "Wimp_OpenWindow",,block%
  WHEN 3: SYS "Wimp_CloseWindow",,block%:quit%=1
REM  WHEN 6: PROCclick
REM  WHEN 9: PROCmenuselect
REM  WHEN 17,18: PROCrecieve
ENDCASE
ENDPROC

:

DEF FNsubtract_day
PROCtoday_day
FOR tmp%=1 TO remove_days%
today_day%-=1
IF today_day%=0 THEN
  REM Previous month
  today_month%-=1
  IF today_month%=0 THEN
    REM Previous year
    today_year%-=1
    today_month%=12
  ENDIF
  today_day%=FNdaysin_month(today_year%,today_month%)
ENDIF
NEXT
=RIGHT$("0"+STR$(today_year%),4)+"-"+RIGHT$("0"+STR$(today_month%),2)+"-"+RIGHT$("0"+STR$(today_day%),2)

:

DEF PROCtoday_day
?now%=3
SYS "OS_Word",14,now%
SYS "OS_ConvertDateAndTime",now%,block%,11,"%ce%yr" TO ,zero%
?zero%=13
today_year%=EVAL(FNstring(block%))
?now%=3
SYS "OS_Word",14,now%
SYS "OS_ConvertDateAndTime",now%,block%,11,"%mn" TO ,zero%
?zero%=13
today_month%=EVAL(FNstring(block%))
?now%=3
SYS "OS_Word",14,now%
SYS "OS_ConvertDateAndTime",now%,block%,11,"%dy" TO ,zero%
?zero%=13
today_day%=EVAL(FNstring(block%))
ENDPROC

:

DEF FNdaysin_month(year%,month%)
CASE month% OF
  WHEN 2 : REM February
    IF (year% MOD 4 = 0) AND ((year% MOD 100 <> 0) OR (year% MOD 400 = 0)) THEN
      days%=29
    ELSE
      days%=28
    ENDIF
  WHEN 4,6,9,11 : days%=30 : REM April, June, September and November   
  OTHERWISE : days%=31
ENDCASE
=days%

:

DEF FNdaysin_year(year%)
IF (year% MOD 4 = 0) AND ((year% MOD 100 <> 0) OR (year% MOD 400 = 0)) THEN
  days%=366
ELSE
  days%=365
ENDIF
=days%

:

DEF FNeval(i$)
LOCAL c$,l%,o$,p%:c$="":l%=LEN(i$):o$="":p%=1
WHILE p%<=l%
  c$=MID$(i$,p%,1)
  IF INSTR("0123456789",c$) > 0 o$+=c$
  p%+=1
ENDWHILE
=EVAL(o$)

:

DEF PROCerror
ON ERROR OFF
VDU4
IF bin_file%<>0 CLOSE#bin_file%
IF file%<>0 CLOSE#file%
REPORT
PRINT;" ";ERL;" in Director:Menus.BinPL.BinInit"
END

:

REM *** File handling routines

:

REM Check to see if a file$ exists in a dir$
REM If it does, numbers are added on to the end of the filename to arrive
REM at a unique filename
REM Returns the (new) filename

DEF FNexist(filename$)
LOCAL exist%,file$,file2$,dir$,c%
exist%=NOT FNfile_valid(filename$,0)
IF NOT exist% THEN =filename$
dir$=FNfile_branch(filename$)
file$=FNfile_leaf(filename$)
count%=0
file_maxlen%=10:file_len%=LEN(file$)
WHILE exist%
  count%+=1:count$=STR$(count%):count_len%=LEN(count$)
  IF file_len%+count_len%>file_maxlen% THEN
    file2$=file$+count$
  ELSE
    file2$=LEFT$(file$,file_maxlen%-count_len%)+count$
  ENDIF
  exist%=NOT FNfile_valid(dir$+"."+file2$,0)
  ENDWHILE
=dir$+"."+file2$

:

REM want% = to what object type you want to find/are looking for
DEF FNfile_valid(file$,want%):LOCAL ans%
SYS "OS_File",17,file$ TO ans%
=(ans%=want%)

:

DEF FNfile_leaf(file$)
LOCAL pos%,temp%
temp%=0
REPEAT
pos%=temp%+1
temp%=INSTR(file$,".",pos%)
UNTIL temp%=0
=MID$(file$,pos%)

:

DEF FNfile_branch(file$)
LOCAL pos%,br$,temp%
IF INSTR(file$,".")=0 THEN
  br$=""
ELSE
  temp%=0
  REPEAT
  pos%=temp%+1
  temp%=INSTR(file$,".",pos%)
  UNTIL temp%=0
  br$=LEFT$(file$,pos%-2)
ENDIF
=br$

:

REM FNfile_line_process
REM returns : processed input from file%

DEF FNfile_line_process
LOCAL line$,text$,a$

text$=GET$#file%
IF text$="" THEN =""
line$=text$:line$=""

FOR loop%=1 TO LEN(text$)
  chr%=ASC(MID$(text$,loop%,1))
  IF chr%>64 AND chr%<91 chr%=chr%+32
  IF chr%>32 line$+=CHR$(chr%)
NEXT

=line$

:

REM *** Misc routines

:

REM lcase : convert line of text to lower case.

DEF FNlcase(text$)
LOCAL Loop%,text2$
FOR Loop%=1 TO LEN(text$)
  chr%=ASC(MID$(text$,Loop%,1))
  IF chr%>64 AND chr%<91 chr%=chr%+32
  text2$+=CHR$(chr%)
NEXT
=text2$

:

REM Return a string zero terminated

DEF FNstring_z(p%):LOCAL a$:a$=""
WHILE ?p%<>0
  a$+=CHR$(?p%):p%+=1
  ENDWHILE:=a$

:

REM Return a string that can be no more than l% chars long

DEF FNstring_l(p%,l%):LOCAL a$:a$=""
WHILE ?p%>31 AND l%>0
  a$+=CHR$(?p%):p%+=1:l%-=1
  ENDWHILE:=a$

:

REM Return a string

DEF FNstring(p%):LOCAL a$:a$=""
WHILE ?p%>31
  a$+=CHR$(?p%):p%+=1
  ENDWHILE:=a$

DEF FNreadvarval(r$)
LOCAL s%
SYS "OS_ReadVarVal",r$,block%,1024 TO ,,s%
=LEFT$(FNstring(block%),s%)
:

DEF FNreport(err$,flag%)
name$="'"+app$+"'"
IF flag% AND 16 name$="Message from "+name$
!block%=255
$(block%+4)=err$+CHR$0
SYS "Wimp_ReportError",block%,flag%,name$ TO ,errclick%
=errclick%

:

DEF PROCwimp_error(err$)
ON ERROR REPORT:PRINT ERL:END
ans%=FNreport(err$,1)
SYS "Wimp_CloseDown"
END

:

REM FNfile_createdir
REM Ensure that the specified directory is created.
REM It will return FALSE if it was unable to create the directory for any reason
REM Logically this should be a function - but I can't be bothered to
REM write the exception handler for it
DEF PROCfile_createdir(dir$)
LOCAL dirpos%, dirtmp$:dirpos%=0:dirtmp$=""
WHILE LEN(dirtmp$)<LEN(dir$)
  dirpos%=INSTR(dir$,".",dirpos%+1)
  dirtmp$=LEFT$(dir$,dirpos%-1)
  OSCLI("CDir "+dirtmp$)
  ENDWHILE
ENDPROC

:
